package com.tcm.user.authentication;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.codec.Md5Utils;
import com.base.core.lang.StringUtils;
import com.base.core.utils.JwtUtils;
import com.base.core.utils.R;
import com.tcm.user.constants.Const;
import com.tcm.user.model.entity.LoginAuth;
import com.tcm.user.constants.enums.BusinessCodeEnum;
import com.tcm.user.constants.enums.LoginTypeEnum;
import com.tcm.user.factory.Authenrizer;
import com.tcm.user.persistence.LoginAuthPersisService;
import com.tcm.user.token.AuthenticationToken;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.security.GeneralSecurityException;
import java.util.Map;

@Component
public class PhonePasswordAuth implements Authenrizer {

    @Autowired
    private LoginAuthPersisService loginAuthPersisService;


    /**
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     * @return
     */
    public R doGetAuthenticationInfo(AuthenticationToken auth) {
        String mobile = (String) auth.getPrincipal();
        if(StringUtils.isEmpty(mobile)){
            return R.fail(BusinessCodeEnum.SMS_PHONE_NOT_EXISTS);
        }
        if(StringUtils.isEmpty(auth.getClientType())){
            return R.fail(BusinessCodeEnum.CLIENT_TYPE_PARAMS_NOT_FOUND);
        }
        if(StringUtils.isEmpty(auth.getCredentials())){
            return R.fail(BusinessCodeEnum.PASSWORD_NOTFOUND);
        }

        LoginAuth loginAuth = loginAuthPersisService.findByMobile(mobile, auth.getClientType());
        if(ObjectUtil.isEmpty(loginAuth)){
            return R.fail(BusinessCodeEnum.IDENTIFIER_NOT_EXISTS);
        }

        String password = loginAuth.getCredential();
        String salt = loginAuth.getSalt();
        String currentPassword = auth.getCredentials().toString();
        try {
            String md5Password = Md5Utils.md5(currentPassword + salt);
            if(!md5Password.equals(password)){
                return R.fail(BusinessCodeEnum.PASSWORD_ERROR);
            }
        } catch (GeneralSecurityException e) {
            R.throwFail(e.getMessage());
        }
        JwtUtils jwtUtils = new JwtUtils();
        Map<String, Object> claims = new HashedMap<>();
        claims.put("clientType", loginAuth.getClientType());
        claims.put("userId", loginAuth.getId());
        String key = Const.REDIS_KEY_USER_SESSION + loginAuth.getId();
        String token = jwtUtils.genToken(loginAuth.getMobile(),claims);
        return R.success(token);
    }

    @Override
    public String supports() {
        return LoginTypeEnum.PHONE_PWD.type();
    }

}
